package team.nmsg.photo.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.transaction.Transactional;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import team.nmsg.ge.system.bean.PageObject;
import team.nmsg.ge.system.dao.INMSCommonDao;
import team.nmsg.ge.system.interf.ISysBean;
import team.nmsg.photo.PhotoUtil;
import team.nmsg.photo.bean.FeaturePhoto;
import team.nmsg.photo.bean.PhotoBean;
import team.nmsg.photo.bean.ProjectBean;
import team.nmsg.photo.dao.IFeatureRepository;
import team.nmsg.photo.dao.IPhotoRepository;
import team.nmsg.photo.dao.IProjectRepository;
import team.nmsg.photo.service.IPhotoService;

@Transactional
@Service
public class PhotoServiceImpl implements IPhotoService {
	
	private static Logger log = LoggerFactory.getLogger(PhotoServiceImpl.class);
	
	@Autowired
	IPhotoRepository photoRep;
	
	@Autowired
	IProjectRepository projectRep ;
	
	@Autowired
	IFeatureRepository featureRep ;
	
	@Autowired
	private INMSCommonDao commonDao;

	@Override
	public ProjectBean createProject(ProjectBean pb) {
		
		long t1 = System.currentTimeMillis();
		pb.setCreateTime( t1 );
		if(  pb.getStatus().intValue() == PhotoUtil.pro_status_start) {
//			pb.setUpdateTime( t1 );
		}
		
		ProjectBean save = projectRep.save(pb);
		
		Long projectId = save.getProjectId();
		
		log.debug( "" + projectId );
		if(StringUtils.isEmpty(pb.getProjectSeq()) ) {
			pb.setProjectSeq(  projectId + "" );
		}
		//创建目录， 拷贝封面资源，重置封面资源, 创建资源图片目录 ;
		String baseDir = PhotoUtil.getProjectDir(save);
		String photoDir = PhotoUtil.getImgsDir(save) ;
		File ff = new File(photoDir);
		ff.mkdirs();
		
		String coverImg = pb.getCoverImg();
		String shareIconImg = pb.getShareIconImg();
		String advertiseImg = pb.getAdvertiseImg();
		
		String coverImgNew = copyBasicImg(coverImg, "coverImg", baseDir);
		pb.setCoverImg( coverImgNew );
		String shareIconImgNew = copyBasicImg(shareIconImg, "shareIconImg", baseDir);
		pb.setShareIconImg( shareIconImgNew );
		String advertiseImgNew = copyBasicImg(advertiseImg, "advertiseImg", baseDir);
		pb.setAdvertiseImg( advertiseImgNew );
		
		//修正基路径
		baseDir = PhotoUtil.userProPath + PhotoUtil.sep +"a"+projectId;
		pb.setImgBaseDir( baseDir );
		
		ProjectBean save2 = projectRep.save(pb);
		
		return save2;
	}
	
	/**
	 * 
	 * @param srcpath
	 * @param dstName
	 * @param baseDir
	 * @return  path of new pic 
	 */
	private String copyBasicImg(String srcpath , String dstName , String baseDir) {
		File f1 = new File(srcpath);
		String f1New = PhotoUtil.sep + dstName +PhotoUtil.getSuffixWithDot(srcpath);
		try {
			FileUtils.copyFile( f1, new File( baseDir + f1New) );
			f1.delete();
		} catch ( Exception e) {
			log.error( "" , e);
		}
		return f1New;
	}
	
	@Override
	public ProjectBean getProject(long parseLong) {
		
		ProjectBean one = projectRep.findOne(parseLong);
		
		Integer picNum = one.getPicNum();
		Session hSession = commonDao.getHSession();
		Criteria criteria = hSession.createCriteria(PhotoBean.class);
		criteria.add(Restrictions.eq("projectId", parseLong));
		criteria.setProjection(Projections.rowCount());
		List listC = criteria.list();
		Object object = listC.get(0);
		int picCount = Integer.parseInt(object.toString());
		if( picNum.intValue()!=picCount  ) {
			one.setPicNum(picCount);
			projectRep.save(one);
		}
		
		return one;
	}

	@Override
	public ProjectBean getProject(String projectSeq) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setProjectsIsShow(String projectIdStrs, boolean parseBoolean) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setProjectsFinished(String projectIdStrs) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public List<Long> delProjects(String projectIdStrs) {
		
		List<Long> failIds = new ArrayList<>();
		
		JSONArray ids = JSONArray.parseArray(projectIdStrs);
		List<Long> logIds = new ArrayList<Long>();
		for (int i = 0; i < ids.size(); i++) {
			Long long1 = ids.getLong(i);
			try {
				
				deleteProject( long1 );
				
			} catch (Exception e) {
				log.error( "" ,e );
				failIds.add(long1);
			}
		}
		return failIds;
		
	}

	private void deleteProject(Long long1) throws IOException {
		ProjectBean findOne = projectRep.findOne(long1);
		String projectDir = PhotoUtil.getProjectDir( findOne );
		projectRep.delete(long1);
		
		String sql = "delete from PhotoBean where projectId=?";
		commonDao.exeuteUpdate(sql, long1);
		File file = new File(projectDir);
		FileUtils.deleteDirectory(file);
	}

	@Override
	public void editProject(ProjectBean pb) {
		
		Long projectId = pb.getProjectId();
		String proTitle = pb.getProTitle();
		Integer accessCount = pb.getAccessCount();
		Integer status = pb.getStatus();
		Integer isShow = pb.getIsShow();
		String shareTitle = pb.getShareTitle();
		String proDesc = pb.getProDesc();
		String shareDesc = pb.getShareDesc();
		
		ProjectBean findOne = projectRep.findOne( projectId) ;
		findOne.setProTitle(proTitle);
		findOne.setAccessCount(accessCount);
		findOne.setStatus(status);
		findOne.setIsShow(isShow);
		findOne.setShareTitle(shareTitle);
		findOne.setProDesc(proDesc);
		findOne.setShareDesc(shareDesc);
		
		findOne.setsOrder(pb.getsOrder());
		findOne.setClasstype(  pb.getClasstype() );
		findOne.setUpdateTime( pb.getUpdateTime()  );
		findOne.setEndTime( pb.getEndTime()  );
		
		if( status.intValue() == PhotoUtil.pro_status_end ) {
//			findOne.setEndTime( System.currentTimeMillis() );
		}
		
		projectRep.save(findOne);
	}

	@Override
	public void delPhoto(String projectIdStr, String photoIdStr) {
		long pid = Long.parseLong(photoIdStr);
		long proid = Long.parseLong(projectIdStr);
		
		ProjectBean proBean = projectRep.findOne(proid);
		PhotoBean findOne = photoRep.findOne(pid);
		
		String imgPath = findOne.getImgPath();
		String img2Path = findOne.getImg2Path();
		String imgsDir = PhotoUtil.getImgsDir(proBean);
		File f1 = new File(imgsDir + imgPath);
		File f2 = new File(imgsDir + img2Path);
//		f1.delete();
//		f2.delete();
		FileUtils.deleteQuietly(f1);
		FileUtils.deleteQuietly(f2);
		photoRep.delete(pid);
	}

	@Override
	public PageObject<ProjectBean> getProjects(ProjectBean criteriaBean ,  int pageSize, int startIndex) {
		PageObject<ProjectBean> page = new PageObject<ProjectBean>();
		
		Session hSession = commonDao.getHSession();
		Criteria criteriaCount = createQuery(criteriaBean, hSession);
		criteriaCount.setProjection(Projections.rowCount());
		List listC = criteriaCount.list();
		Object object = listC.get(0);
		long parseLong = Long.parseLong(object.toString());
		page.setSumCount(parseLong);
		
		Criteria criteria = createQuery(criteriaBean, hSession);
		criteria.addOrder(Order.asc("sOrder"));
		criteria.addOrder(Order.desc("createTime"));
		criteria.setFirstResult(startIndex);
		criteria.setMaxResults(pageSize);
		List list = criteria.list();
		page.setCurrentEntitys(list);
		
		
		return page;
	}
	
	private Criteria createQuery( ProjectBean criteriaBean ,Session hSession ) {
		Criteria criteria = hSession.createCriteria(ProjectBean.class);
		
		String proSeq = criteriaBean.getProjectSeq();
		String proTitle = criteriaBean.getProTitle();
		if(  !StringUtils.isEmpty(proSeq) ) {
			criteria.add(Restrictions.like("projectSeq", "%"+proSeq+"%"));
		}
		if(  !StringUtils.isEmpty(proTitle) ) {
			criteria.add(Restrictions.like("proTitle", "%"+proTitle+"%"));
		}
		return criteria;
	}

	@Override
	public String editProjectPic(String utype, String pid, String toReplaceImg) {
		
		long parseLong = Long.parseLong( pid );
		ProjectBean findOne = projectRep.findOne( parseLong ) ;
	
		String baseDir = PhotoUtil.getProjectDir(findOne);
		
		String srcImgname = "";
		String suffix = "_"+ System.currentTimeMillis();
		String copyBasicImg = "";
		if( PhotoUtil.imgtype_cover.equals(utype)  ) {
			srcImgname = findOne.getCoverImg();
			copyBasicImg = copyBasicImg( toReplaceImg , PhotoUtil.imgtype_cover+suffix , baseDir);
			findOne.setCoverImg(copyBasicImg);
		}else if(   PhotoUtil.imgtype_share.equals(utype) ) {
			srcImgname = findOne.getShareIconImg();
			copyBasicImg = copyBasicImg( toReplaceImg , PhotoUtil.imgtype_share+suffix , baseDir);
			findOne.setShareIconImg(copyBasicImg);
		}else if (   PhotoUtil.imgtype_ad.equals(utype) ){
			srcImgname = findOne.getAdvertiseImg();
			copyBasicImg = copyBasicImg( toReplaceImg , PhotoUtil.imgtype_ad+suffix , baseDir);
			findOne.setAdvertiseImg(copyBasicImg);
		}
		projectRep.save(findOne);
		
		new File( baseDir + srcImgname).delete();
		return findOne.getImgBaseDir() +copyBasicImg;
	}

	@Override
	public PhotoBean saveImg(String projectIdStr, MultipartFile file1 ) {
		
		long parseLong = Long.parseLong( projectIdStr );
		ProjectBean findOne = projectRep.findOne( parseLong ) ;
		String imgDir = PhotoUtil.getImgsDir(findOne);
		
		String sfilename = file1.getOriginalFilename();
		String filenameWithoutSuffix = UUID.randomUUID().toString().replace("-", "");
		String filename =  filenameWithoutSuffix + PhotoUtil.getSuffixWithDot(sfilename);
		String filepath = imgDir + PhotoUtil.sep + filename;
		File newFile = new File(filepath);
		try {
			file1.transferTo( newFile );
		} catch ( Exception e) {
			log.error( "" ,e );
		}  
		
		PhotoBean photoBean = new PhotoBean();
		photoBean.setProjectId(parseLong);
		photoBean.setCreateTime(System.currentTimeMillis());
		photoBean.setImgPath( PhotoUtil.sep + filename );
		
		int[] wh = PhotoUtil.getImgWidthHeight( newFile );
		photoBean.setImgWidth( wh[0] );
		photoBean.setImgHeight( wh[1] );
		
		long srcFileSize = newFile.length();
//		if(  srcFileSize <= PhotoUtil.SIZE_100KB ) {
//			photoBean.setImg2Path( PhotoUtil.sep + filename );
//			photoBean.setImgWidth2( wh[0] );
//			photoBean.setImgHeight2( wh[1] );
//		} else {
			//缩略图  生成缩略图
			String thumb = PhotoUtil.sep + filenameWithoutSuffix+ PhotoUtil.THUMB_FLAG + PhotoUtil.DOT_JPG;
			String thumbPath = imgDir + thumb;
			int[] cutXYWH = PhotoUtil.getCutXYWH( wh[0], wh[1] );
			try {
//				PhotoUtil.cutAndReduceImage( filepath, thumbPath,  cutXYWH[0] , cutXYWH[1] , cutXYWH[2] , cutXYWH[3] );
				PhotoUtil.cutAndReduceImage2( filepath, thumbPath);
				photoBean.setImg2Path( thumb );
				photoBean.setImgWidth2( PhotoUtil.THUMB_W );
				photoBean.setImgHeight2( PhotoUtil.THUMB_H   );
			} catch (Exception e) {
				log.error( "" ,e );
				photoBean.setImg2Path( PhotoUtil.sep + filename );
				photoBean.setImgWidth2( wh[0] );
				photoBean.setImgHeight2( wh[1] );
			}
//		}
		
		
		PhotoBean save = photoRep.save(photoBean);
		
		return save;
	}

	@Override
	public PageObject<PhotoBean> getPhotos(PhotoBean criteriaBean, int pageSize, int startIndex) {
		
		PageObject<PhotoBean> page = new PageObject<>();
		
		Session hSession = commonDao.getHSession();
		Criteria criteriaCount = createPhotoQuery(criteriaBean, hSession);
		criteriaCount.setProjection(Projections.rowCount());
		List listC = criteriaCount.list();
		Object object = listC.get(0);
		long parseLong = Long.parseLong(object.toString());
		page.setSumCount(parseLong);
		
		Criteria criteria = createPhotoQuery(criteriaBean, hSession);
		criteria.addOrder(Order.desc("createTime"));
		criteria.setFirstResult(startIndex);
		criteria.setMaxResults(pageSize);
		List list = criteria.list();
		page.setCurrentEntitys(list);
		
		if( criteriaBean.getIsQueryProject() ) {
			Long projectId = criteriaBean.getProjectId();
			ProjectBean findOne = projectRep.findOne(projectId);
			page.setExtInfo(findOne);
		}
		
		return page;
	}

	private Criteria createPhotoQuery(PhotoBean criteriaBean, Session hSession) {

		Criteria criteria = hSession.createCriteria(PhotoBean.class);
		Long projectId = criteriaBean.getProjectId();
		criteria.add(Restrictions.eq("projectId", projectId));
		return criteria;

	}

	@Override
	public void addAccessCount(long projectId) {
		
		ProjectBean findOne = projectRep.findOne( projectId) ;
		Integer accessCount = findOne.getAccessCount();
		if( accessCount == null ) {
			accessCount = 0;
		}
		findOne.setAccessCount(accessCount +1 );
		projectRep.save(findOne);
	}
	
	public PageObject<ProjectBean> getPros(ProjectBean criteriaBean, int pageSize, int startIndex, boolean isGetActive){
		
		PageObject<ProjectBean> page = new PageObject<ProjectBean>();
		
		criteriaBean.setStatus( PhotoUtil.pro_status_end );
		Session hSession = commonDao.getHSession();
		Criteria criteriaCount = createProQueryForGuest(criteriaBean, hSession);
		criteriaCount.setProjection(Projections.rowCount());
		List listC = criteriaCount.list();
		Object object = listC.get(0);
		long parseLong = Long.parseLong(object.toString());
		page.setSumCount(parseLong);
		Criteria criteria = createProQueryForGuest(criteriaBean, hSession);
		criteria.addOrder(Order.desc("createTime"));
		criteria.setFirstResult(startIndex);
		criteria.setMaxResults(pageSize);
		List list = criteria.list();
		page.setCurrentEntitys(list);
		
		
		criteriaBean.setStatus( PhotoUtil.pro_status_start );
		Criteria criteriaActive = createProQueryForGuest(criteriaBean, hSession);
		criteriaActive.addOrder(Order.desc("createTime"));
		criteriaActive.setFirstResult(startIndex);
		criteriaActive.setMaxResults(pageSize);
		List activeList = criteriaActive.list();
		page.setExtInfo(  activeList );
		
		
		return page;
	}
	
	private Criteria createProQueryForGuest( ProjectBean criteriaBean ,Session hSession ) {
		Criteria criteria = hSession.createCriteria(ProjectBean.class);
		
		String proTitle = criteriaBean.getProTitle();

		if(  !StringUtils.isEmpty(proTitle) ) {
			criteria.add(Restrictions.like("proTitle", "%"+proTitle+"%"));
		}
		
		Integer status = criteriaBean.getStatus();
		if( status!=null ) {
			criteria.add(Restrictions.eq("status", status));
		}
		criteria.add(  Restrictions.eq("isShow", PhotoUtil.pro_show)    );
		
		return criteria;
	}

	@Override
	public FeaturePhoto addFeature(FeaturePhoto featurePhoto) {
		
		featurePhoto.setCreateTime(System.currentTimeMillis());
		
		FeaturePhoto save = featureRep.save(featurePhoto);
		
		return save;
	}

	@Override
	public List<FeaturePhoto> getFeatures(FeaturePhoto featurePhoto) {
		
		List<FeaturePhoto> findAll = featureRep.findAll();
		
		return findAll;
	}
	
	public boolean delAFeature(FeaturePhoto featurePhoto) {
		Long getfId = featurePhoto.getfId();
		
		featureRep.delete(getfId);
		
		return true;
	}

	@Override
	public JSONObject getMainPage() {
		JSONObject retObj= new JSONObject();
		
		Session hSession = commonDao.getHSession();
		//正在直播
		Criteria criteriaActive = hSession.createCriteria(ProjectBean.class);
		criteriaActive.add(  Restrictions.eq("isShow", PhotoUtil.pro_show)    );
		criteriaActive.add( Restrictions.eq("status", PhotoUtil.pro_status_start) );
		List activeList = criteriaActive.list();
		//往期推荐
		Criteria criteriaEnd = hSession.createCriteria(ProjectBean.class);
		criteriaEnd.add(  Restrictions.eq("isShow", PhotoUtil.pro_show)    );
		criteriaEnd.add( Restrictions.eq("status", PhotoUtil.pro_status_end) );
		criteriaEnd.addOrder(Order.asc("sOrder") );
		criteriaEnd.addOrder(Order.desc("createTime"));
		criteriaEnd.setFirstResult(0);
		criteriaEnd.setMaxResults(10);
		List endListTop = criteriaEnd.list();
		//查询精选
		List findAll = featureRep.findAll();
		
		JSONArray actives = listToArr(activeList);
		JSONArray top10 = listToArr(endListTop);
		JSONArray features = listToArr(findAll);
		retObj.put("actives", actives);
		retObj.put("top10", top10);
		retObj.put("features", features);
		
		return retObj;
	}
	
	private JSONArray listToArr( List<ISysBean> beans ) {
		JSONArray arr = new JSONArray();
		
		for( ISysBean bean : beans) {
			arr.add(bean.toJson());
		}
		
		return arr;
	}

	@Override
	public PageObject<ProjectBean> getProsByCriteria(ProjectBean criteriaBean, int pageSize, int startIndex) {
		
		PageObject<ProjectBean> page = new PageObject<ProjectBean>();
		Session hSession = commonDao.getHSession();
		
		Criteria criteriaCount = createProQueryForGuest2(criteriaBean, hSession);
		criteriaCount.setProjection(Projections.rowCount());
		List listC = criteriaCount.list();
		Object object = listC.get(0);
		long parseLong = Long.parseLong(object.toString());
		page.setSumCount(parseLong);
		
		Criteria criteria = createProQueryForGuest2(criteriaBean, hSession);
		criteria.addOrder(Order.desc("createTime"));
		criteria.setFirstResult(startIndex);
		criteria.setMaxResults(pageSize);
		List list = criteria.list();
		page.setCurrentEntitys(list);
		
		
		return page;
	}
	
	//  proTitle  status  classtype 
	private Criteria createProQueryForGuest2( ProjectBean criteriaBean ,Session hSession ) {
		Criteria criteria = hSession.createCriteria(ProjectBean.class);
		
		
		String proTitle = criteriaBean.getProTitle();

		if(  !StringUtils.isEmpty(proTitle) && !"-1".equals(proTitle) ) {
			criteria.add(Restrictions.like("proTitle", "%"+proTitle+"%"));
		}
		
		Integer status = criteriaBean.getStatus();
		if( status!=null && status.intValue()!=-1 ) {
			criteria.add(Restrictions.eq("status", status));
		}
		
		String classtype = criteriaBean.getClasstype();
		if( classtype!=null && !"-1".equals(classtype) ) {
			criteria.add(  Restrictions.eq("classtype", classtype)   );
		}
		
		criteria.add(  Restrictions.eq("isShow", PhotoUtil.pro_show)    );
		
		return criteria;
	}

	@Override
	public boolean resetPOrder() {
		
		String sql = "update ProjectBean set sOrder=10000";
		commonDao.exeuteUpdate(sql);
		
		return true;
	}
	
}
